package com.mxx.tomcat.util;

import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author itzgyw
 * @Date 2020-03-23
 * @Time 22:19
 * @Description:
 */
@Slf4j
public class IPSearchUtil {
    private static Map<String, String> dbFileMap;

    static {
        try {
            dbFileMap = new HashMap<>();
            String url = ResourceUtils.getURL("classpath:ip2region.db").getPath();

            int index = url.indexOf(".jar");
            if (index == -1) {
                dbFileMap.put("dbFile", url);
            } else {
                for (int i = index - 1; i >= 0; i--) {
                    char spitChar = url.charAt(i);
                    if (spitChar == 47 || spitChar == 92) {

                        index = i;
                        break;
                    }
                }

                String filePath = url.substring(6, index);

                InputStream inputStream = IPSearchUtil.class.getClassLoader().getResourceAsStream("ip2region.db");

                if (inputStream == null) {
                    throw new RuntimeException("纯真IP数据库不存在 ！！！");
                }
                if (!filePath.startsWith(File.separator)) {
                    filePath = File.separator + filePath;
                }

                File file = new File(filePath + "/ip2region.db");

                if (file.exists()) {
                    file.delete();
                    file.createNewFile();
                }


                byte[] bt = new byte[1024];
                int len = 0;
                FileOutputStream outputStream = new FileOutputStream(file);
                while ((len = inputStream.read(bt)) != -1) {
                    outputStream.write(bt, 0, len);
                    outputStream.flush();
                }
                outputStream.close();
                inputStream.close();
                dbFileMap.put("dbFile", filePath + "/ip2region.db");

            }
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }

    public static IpUtil.CityInfo getCityInfo(String ip) {

        File file = new File(dbFileMap.get("dbFile"));
        if (!file.exists()) {
            System.out.println("Error: Invalid ip2region.db file");
        }

        //查询算法
        int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree

        try {
            DbConfig config = new DbConfig();
            DbSearcher searcher = new DbSearcher(config, dbFileMap.get("dbFile"));


            Method method = null;
            switch (algorithm) {
                case DbSearcher.BTREE_ALGORITHM:
                    method = searcher.getClass().getMethod("btreeSearch", String.class);
                    break;
                case DbSearcher.BINARY_ALGORITHM:
                    method = searcher.getClass().getMethod("binarySearch", String.class);
                    break;
                case DbSearcher.MEMORY_ALGORITYM:
                    method = searcher.getClass().getMethod("memorySearch", String.class);
                    break;
            }

            DataBlock dataBlock = null;
            if (Util.isIpAddress(ip) == false) {
                System.out.println("Error: Invalid ip address");
            }

            dataBlock = (DataBlock) method.invoke(searcher, ip);

            return new IpUtil.CityInfo(dataBlock.getRegion());

        } catch (Exception e) {
            log.error("getCity fail , IP =  " + ip, e);
            e.printStackTrace();
        }

        return new IpUtil.CityInfo().setCity("错误IP").setCountry("错误IP")
                .setProvider("错误IP").setProvince("错误IP");
    }
}
